﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace AppMain
{
    class LogInfo
    {
        private string _foldername = "LogFiles";
        private string _logFilename = "TransferRecord.txt";
        private string _appendText = "Exported at";
        private static LogInfo _this = new LogInfo();
        public Mutex _logInUse = new Mutex();
        private StreamWriter _log;
        private DateTime _date;

        // called when the class is instantiated. All initialization and setup should
        // be done in this routine.
        // Because the log file is only established once, it is configured here.
        // The logging takes place below, but it is only necessary to initilize the log
        // once. Because this is a Singleton Class, the Log is only configured a single
        // time
        LogInfo()
        {
            _logInUse.WaitOne();
            if (Directory.Exists(_foldername) == false)
            {
                Directory.CreateDirectory(_foldername);
            }

            _date = DateTime.Now;
            try
            {
                _log = new StreamWriter(string.Format("{0}\\{1}_{2}",
                                                            _foldername,
                                                            _date.ToString("yyyyMMdd"),
                                                            _logFilename),
                                                            true);
            }
            catch (SystemException error)
            {
                var mb = MessageBox.Show(error.Message);
                _log = null;
            }

            _logInUse.ReleaseMutex();
        }

        // class destructor, close the log
        ~LogInfo()
        {
            // Apparently C# handles closing the file without doing it in the destructor
            //_log.Close();
        }

        // Create Singleton for LogData. Hence all classes will reference the same object
        public static LogInfo GetObject
        {
            get
            {
                return _this;
            }
        }


        public void Write(string info)
        {
            // if a Thread calls this function, it will hit this mutex and
            // stop until the other application has completed it's write
            _logInUse.WaitOne();
            DateTime date = DateTime.Now;
            // Make a new log file each day, but only if there is data for in it.
            if ((date.Subtract(_date)).Days >= 1)
            {
                _log.Close();
                _log = new StreamWriter(string.Format("{0}\\{1}_{2}",
                                                            _foldername,
                                                            _date.ToString("yyyyMMdd"),
                                                            _logFilename),
                                                            true);
            }
            _log.WriteLine("{0}(UTC) {1}", DateTime.Now.ToUniversalTime().ToString("o"), info);
            _logInUse.ReleaseMutex();
        }

        public string ExportLogFile()
        {
            // if a Thread calls this function, it will hit this mutex and
            // stop until the other application has completed it's write.
            // The file is actually closed in this function, so it needs
            // to be locked to avoid exceptions
            string returnText = "Error, Function terminated unexpectedly";
            _logInUse.WaitOne();
            if (_log == null)
            {
                _logInUse.ReleaseMutex();
                return "Error, No log Files Exists";
            }

            _log.Close();

            if (Directory.Exists(_foldername) == false)
            {
                Directory.CreateDirectory(_foldername);
            }

            string theDate = _date.ToString("yyyyMMdd");
            string filename = string.Format("{0}\\{1}_{2}", _foldername, theDate, _logFilename);
            string newFilename  = string.Format("{0}\\{1}_{2}_{3} {4}", _foldername, theDate, _logFilename, _appendText, DateTime.Now.ToString("hh-mm-ss"));
            try
            {
                File.Copy(filename, newFilename, true);
            }
            catch (SystemException error)
            {
                var mb = MessageBox.Show(error.Message);
                returnText = "Error, copying log file failed";
            }

            try
            {
                _log = new StreamWriter(string.Format("{0}\\{1}_{2}",
                                                            _foldername,
                                                            _date.ToString("yyyyMMdd"),
                                                            filename),
                                                            true);
            }
            catch (SystemException error)
            {
                var mb = MessageBox.Show(error.Message);
                _log = null;
                //returnText = "Error, log file could not be re-created or re-opened";
            }
            _logInUse.ReleaseMutex();
            return returnText;
        }
        public void Close()
        {
            _logInUse.WaitOne();
            _log.Close();
            _logInUse.ReleaseMutex();
        }
    }
}
